home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 1.iso / DEMON / RISCOS2 / TCP_131S.ARC / c / AX25DUMP < prev    next >
Text File  |  1994-03-03  |  12KB  |  318 lines

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <time.h>
  4. #include "global.h"
  5. #include "mbuf.h"
  6. #include "ax25.h"
  7. #include "timer.h"
  8. #include "lapb.h"
  9. #include "trace.h"
  10. #include "arp.h"
  11. #include "ip.h"
  12. #include "misc.h"
  13. #include "netrom.h"  
  14.  
  15. static void netrom_dump(struct mbuf **);
  16.  
  17. /* Dump an AX.25 packet header */
  18. void ax25_dump(struct mbuf **bpp, int check)
  19. {
  20.         char tmp[20], tmp1[20];
  21.         char control,pid,seg,ipcam;
  22.         int16 type;
  23.         struct ax25 hdr;
  24.         struct ax25_addr *hp;
  25.         int unsegmented;
  26.         char header[128];
  27.         char buf[80];
  28.         struct mbuf *temp;
  29.  
  30.         check = check;
  31.  
  32.         /* Extract the address header */
  33.         if(ntohax25(&hdr,bpp) < 0){
  34.                 /* Something wrong with the header */
  35.                 twprintf("AX25: bad header\n");
  36.                 return;
  37.         }
  38.  
  39.         pax25(tmp,&hdr.source);
  40.         pax25(tmp1,&hdr.dest);
  41.         sprintf(header,"AX25: %s->%s ", tmp, tmp1);
  42.  
  43.         if(hdr.ndigis > 0){
  44.                 strcat(header,"v ");
  45.                 for(hp = &hdr.digis[0]; hp < &hdr.digis[hdr.ndigis]; hp++){
  46.                         /* Print digi string */
  47.                         pax25(tmp,hp);
  48.                         strcat(header,tmp);
  49.                         strcat(header,(hp->ssid & REPEATED) ? "*":" ");
  50.                 }
  51.         }
  52.  
  53.         if(pullone(bpp,&control) != 1){
  54.                 twprintf("%s\n",header);
  55.                 return;
  56.         }
  57.  
  58.         type = ftype(control);
  59.         strcat(header,decode_type(type));
  60.         /* Dump poll/final bit */
  61.         if(control & PF){
  62.                 switch(hdr.cmdrsp){
  63.                 case COMMAND:
  64.                         strcat(header,"(P)");
  65.                         break;
  66.                 case RESPONSE:
  67.                         strcat(header,"(F)");
  68.                         break;
  69.                 default:
  70.                         strcat(header,"(P/F)");
  71.                         break;
  72.                 }
  73.         }
  74.  
  75.         twputs(header);
  76.  
  77.         /* Dump sequence numbers */
  78.         if((type & 0x3) != U)   /* I or S frame? */
  79.                 twprintf(" NR=%d",(control>>5)&7);
  80.  
  81.         if(type == I || type == UI){
  82.                 if(type == I)
  83.                         twprintf(" NS=%d",(control>>1)&7);
  84.                 /* Decode I field */
  85.                 if(pullone(bpp,&pid) == 1){     /* Get pid */
  86.                         if(pid == PID_SEGMENT){
  87.                                 unsegmented = 0;
  88.                                 pullone(bpp,&seg);
  89.                                 twprintf("%s remain %u",   (seg & SEG_FIRST) ?
  90.                                         " First seg;" : "", seg & SEG_REM);
  91.                                 if(seg & SEG_FIRST)
  92.                                         pullone(bpp,&pid);
  93.                         } else
  94.                                 unsegmented = 1;
  95.  
  96.                         temp = *bpp;
  97.                         if (pid == PID_NO_L3 && temp->cnt >= 20
  98.                             && temp->data[0] == 0x45
  99.                             && temp->data[1] == 0x00
  100.                             && temp->data[2] < 0x02){
  101.                                 pid = PID_IP;
  102.                                 ipcam = 1;
  103.                         }
  104.                         else
  105.                                 ipcam = 0;
  106.  
  107.                         if(pid == PID_SEGMENT)
  108.                                 twprintf("\n");
  109.                         else{
  110.                                 twprintf(" pid=");
  111.                                 switch(pid){
  112.                                         case PID_ARP:
  113.                                                 twprintf("ARP\n");
  114.                                                 arp_dump(bpp);
  115.                                                 break;
  116.                                         case PID_NETROM:
  117.                                                 twprintf("NET/ROM\n");
  118.                                                 netrom_dump(bpp);
  119.                                                 break;
  120.                                         case PID_IP:
  121.                                                 twprintf("IP\n");
  122.                                                 ip_dump(bpp,unsegmented);
  123.                                                 break;
  124.                                         case PID_NO_L3:
  125.                                                 twprintf("Text\n");
  126.                                                 break;
  127.                                         default:
  128.                                                 twprintf("0x%x\n",pid);
  129.                                 }
  130.                         }
  131.                 }
  132.         } else if(type == FRMR && pullup(bpp,tmp,3) == 3){
  133.                         sprintf(buf," Vr = %d Vs = %d",(tmp[1] >> 5) & MMASK,
  134.                                 (tmp[1] >> 1) & MMASK);
  135.                         if(tmp[2] & W)
  136.                                 strcat(buf," Invalid control field");
  137.                         if(tmp[2] & X)
  138.                                 strcat(buf," Illegal I-field");
  139.                         if(tmp[2] & Y)
  140.                                 strcat(buf," Too-long I-field");
  141.                         if(tmp[2] & Z)
  142.                                 strcat(buf," Invalid seq number");
  143.                         twprintf(":\n%s %s\n",decode_type(ftype(tmp[0])),buf);
  144.                 }
  145.                 else
  146.                         twprintf("\n");
  147. }
  148. /* Display NET/ROM network and transport headers */
  149. static void netrom_dump(struct mbuf **bpp)
  150. {
  151.         struct ax25_addr src,dest;
  152.         char x;
  153.         char tmp[16];
  154.         char thdr[5];
  155.         register i;
  156.  
  157.         if(bpp == NULLBUFP || *bpp == NULLBUF)
  158.                 return;
  159.         /* See if it is a routing broadcast */
  160.         if(uchar(*(*bpp)->data) == 0xff) {
  161.                 pullone(bpp,tmp);              /* Signature */
  162.                 pullup(bpp,tmp,ALEN);
  163.                 tmp[ALEN] = '\0';
  164.                 twprintf("NET/ROM Routing: %s\n",tmp);
  165.                 for(i = 0;i < 11;i++) {
  166.                         if (pullup(bpp,tmp,AXALEN) < AXALEN)
  167.                                 break;
  168.                         memcpy(src.call,tmp,ALEN);
  169.                         src.ssid = tmp[ALEN];
  170.                         pax25(tmp,&src);
  171.                         twprintf("        %12s",tmp);
  172.                         pullup(bpp,tmp,ALEN);
  173.                         tmp[ALEN] = '\0';
  174.                         twprintf("%8s",tmp);
  175.                         pullup(bpp,tmp,AXALEN);
  176.                         memcpy(src.call,tmp, ALEN);
  177.                         src.ssid = tmp[ALEN];
  178.                         pax25(tmp,&src);
  179.                         twprintf("    %12s", tmp);
  180.                         pullone(bpp,tmp);
  181.                         twprintf("    %3u\n", (unsigned)uchar(tmp[0]));
  182.                 }
  183.                 return;
  184.         }
  185.         /* Decode network layer */
  186.         pullup(bpp,tmp,AXALEN);
  187.         memcpy(src.call,tmp,ALEN);
  188.         src.ssid = tmp[ALEN];
  189.         pax25(tmp,&src);
  190.         twprintf("NET/ROM: %s",tmp);
  191.  
  192.         pullup(bpp,tmp,AXALEN);
  193.         memcpy(dest.call,tmp,ALEN);
  194.         dest.ssid = tmp[ALEN];
  195.         pax25(tmp,&dest);
  196.         twprintf("->%s",tmp);
  197.  
  198.         pullup(bpp,&x,1);
  199.         twprintf(" ttl %d\n",uchar(x));
  200.  
  201.         /* Read first five bytes of "transport" header */
  202.         pullup(bpp,thdr,5);
  203.         switch((thdr[4] & 0xf) | (thdr[0] & IPVERSION << 4)){
  204.         case 0: /* network PID extension */
  205.         case (0 | IPVERSION << 4):      /* try to handle old IP format */
  206.         case (1 | IPVERSION << 4):      /* try to handle old IP format */
  207.         case (2 | IPVERSION << 4):      /* try to handle old IP format */
  208.         case (3 | IPVERSION << 4):      /* try to handle old IP format */
  209.         case (4 | IPVERSION << 4):      /* try to handle old IP format */
  210.         case (5 | IPVERSION << 4):      /* try to handle old IP format */
  211.         case (6 | IPVERSION << 4):      /* try to handle old IP format */
  212.                 if (thdr[0] == NRPROTO_IP && thdr[1] == NRPROTO_IP)
  213.                         ip_dump(bpp,1) ; /* new format of IP over NET/ROM */
  214.                 else
  215.                         {
  216.                         twprintf("         protocol family %x, proto %x",
  217.                                         uchar(thdr[0]), uchar(thdr[1])) ;
  218.                         /* Try to use IPVERSION value to descriminate */
  219.                         /* maybe it's an old format IP datagram! */
  220.                         if ((thdr[0] & 0xf0) == IPVERSION << 4)
  221.                                 {
  222.                                 struct mbuf *thbuf, *save ;
  223.                                 twprintf("  -  old format IP\n");         
  224.                                 if ((thbuf = alloc_mbuf(5)) == NULLBUF) break ;
  225.                                 thbuf->cnt = 5 ;
  226.                                 memcpy(thbuf->data,thdr,5) ;
  227.                                 save = *bpp ;
  228.                                 *bpp = thbuf ;
  229.                                 append(bpp,save) ;
  230.                                 ip_dump(bpp,1) ;
  231.                                 }
  232.                         }
  233.                 break;
  234.         case 1: /* Connect request */
  235.                 twprintf("         conn rqst: ckt %d/%d",uchar(thdr[0]),uchar(thdr[1]));
  236.                 pullone(bpp,&x);
  237.                 twprintf(" wnd %d",x);
  238.                 pullup(bpp,(char *)&src,AXALEN);
  239.                 pax25(tmp,&src);
  240.                 twprintf(" %s",tmp);
  241.                 pullup(bpp,(char *)&dest,AXALEN);
  242.                 pax25(tmp,&dest);
  243.                 twprintf("@%s",tmp);
  244.                 break;
  245.         case 2: /* Connect acknowledgement */
  246.                 twprintf("         conn ack: ur ckt %d/%d my ckt %d/%d",
  247.                         uchar(thdr[0]), uchar(thdr[1]), uchar(thdr[2]),
  248.                         uchar(thdr[3]));
  249.                 pullone(bpp,&x);
  250.                 twprintf(" wnd %d",x);
  251.                 break;
  252.         case 3: /* Disconnect request */
  253.                 twprintf("         disc: ckt %d/%d",uchar(thdr[0]),uchar(thdr[1]));
  254.                 break;
  255.         case 4: /* Disconnect acknowledgement */
  256.                 twprintf("         disc ack: ckt %d/%d",uchar(thdr[0]),uchar(thdr[1]));
  257.                 break;
  258.         case 5: /* Information (data) */
  259.                 twprintf("         info: ckt %d/%d",uchar(thdr[0]),uchar(thdr[1]));
  260.                 twprintf(" txseq %d rxseq %d",uchar(thdr[2]), uchar(thdr[3]));
  261.                 break;
  262.         case 6: /* Information acknowledgement */
  263.                 twprintf("         info ack: ckt %d/%d",uchar(thdr[0]),uchar(thdr[1]));
  264.                 twprintf(" txseq %d rxseq %d",uchar(thdr[2]), uchar(thdr[3]));
  265.                 break;
  266.         default:
  267.                 twprintf("         unknown transport type %d", thdr[4] & 0x0f) ;
  268.                 /* Try to use IPVERSION value to descriminate */
  269.                 /* maybe it's an old format IP datagram! */
  270.                 if ((thdr[0] & 0xf0) == IPVERSION << 4)
  271.                         {
  272.                         struct mbuf *thbuf, *save ;
  273.                         twprintf("  -  old format IP\n");         
  274.                         if ((thbuf = alloc_mbuf(5)) == NULLBUF) break ;
  275.                         thbuf->cnt = 5 ;
  276.                         memcpy(thbuf->data,thdr,5) ;
  277.                         save = *bpp ;
  278.                         *bpp = thbuf ;
  279.                         append(bpp,save) ;
  280.                         ip_dump(bpp,1) ;
  281.                         }
  282.                 break;
  283.         }
  284.         if(thdr[4] & 0x80)
  285.                 twprintf(" CHOKE");
  286.         if(thdr[4] & 0x40)
  287.                 twprintf(" NAK");
  288.         twprintf("\n");
  289. }
  290. char *decode_type(int16 type)
  291. {
  292.         switch(uchar(type)){
  293.         case I:
  294.                 return "I";
  295.         case SABM:
  296.                 return "SABM";
  297.         case DISC:
  298.                 return "DISC";
  299.         case DM:
  300.                 return "DM";
  301.         case UA:
  302.                 return "UA";
  303.         case RR:
  304.                 return "RR";
  305.         case RNR:
  306.                 return "RNR";
  307.         case REJ:
  308.                 return "REJ";
  309.         case FRMR:
  310.                 return "FRMR";
  311.         case UI:
  312.                 return "UI";
  313.         default:
  314.                 return "[invalid]";
  315.         }
  316. }
  317.  
  318.